package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.config.VodProperties;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.atguigu.tingshu.vo.album.TrackMediaInfoVo;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;


@Service
@Slf4j
public class VodServiceImpl implements VodService {

    @Autowired
    private VodProperties vodProperties;

    @Override
    public Map<String, Object> uploadTrack(MultipartFile file) {
        String fileId = null;
        String mediaUrl = null;

        //1.构建一个vod 上传客户端对象
        VodUploadClient client = new VodUploadClient(vodProperties.getSecretId(), vodProperties.getSecretKey());
        //2.构造上传请求对象
        VodUploadRequest request = new VodUploadRequest();
        //设置将上传文件保存到本地暂存的临时目录路径
        String tempPath = UploadFileUtil.uploadTempPath(vodProperties.getTempPath(), file);
        request.setMediaFilePath(tempPath);
        //给请求设置并发上传的分片数量
        request.setConcurrentUploadNumber(5);
        //3.调用上传
        try {
            VodUploadResponse response = client.upload(vodProperties.getRegion(), request);
            mediaUrl = response.getMediaUrl();
            fileId = response.getFileId();
            log.info("Upload Success");
        } catch (Exception e) {
            // 业务方进行异常处理
            log.error("Upload Err", e);
            throw new GuiguException(201, "上传失败");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("mediaFileId", fileId);
        map.put("mediaUrl", mediaUrl);
        return map;
    }

    /**
     * 根据MediaFileId获取音频文件信息
     *
     * @param mediaFileId 音频文件唯一标识符
     * @return 封装了音频信息的对象vo
     */
    @Override
    @SneakyThrows
    public TrackMediaInfoVo getMediaUrlByMediaFileId(String mediaFileId) {
        VodClient vodClient = getVodClient();
        //3.实例化请求对象
        DescribeMediaInfosRequest request = new DescribeMediaInfosRequest();
        //为请求设置请求参数
        request.setFileIds(new String[]{mediaFileId});
        //4.调用请求对象,获取信息

        TrackMediaInfoVo trackMediaInfoVo = new TrackMediaInfoVo();
        DescribeMediaInfosResponse respose = vodClient.DescribeMediaInfos(request);
        MediaInfo[] mediaInfoSet = respose.getMediaInfoSet();
        //5.对指定信息进行封装
        if (mediaInfoSet != null && mediaInfoSet.length > 0) {
            MediaInfo mediaInfo = mediaInfoSet[0];
            MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
            MediaMetaData metaData = mediaInfo.getMetaData();
            Float audioDuration = metaData.getAudioDuration();
            trackMediaInfoVo.setSize(metaData.getSize());
            trackMediaInfoVo.setDuration(audioDuration);
            trackMediaInfoVo.setMediaUrl(basicInfo.getMediaUrl());
            trackMediaInfoVo.setType(basicInfo.getType());

            //6.将封装对象返回
            return trackMediaInfoVo;
        }
        return null;
    }

    /**
     * 根据MediaFileId删除指定文件
     *
     * @param mediaFileId 媒体文件的唯一标识符
     */
    @Override
    @SneakyThrows
    public void removeMedia(String mediaFileId) {
        //1.获取客户端对象
        VodClient vodClient = getVodClient();
        //2.声明删除请求
        DeleteMediaRequest request = new DeleteMediaRequest();
        //设置请求参数
        request.setFileId(mediaFileId);
        //3.使用客户端对象调用删除请求
        DeleteMediaResponse response = vodClient.DeleteMedia(request);
        log.info("执行vod删除流媒体请求:{}", JSON.toJSONString(response));
    }


    /**
     * 获取vod客户端对象
     * @return vod客户端对象
     */
    @NotNull
    private VodClient getVodClient() {
        //1.实例化一个认证对象
        Credential credential = new Credential(vodProperties.getSecretId(), vodProperties.getSecretKey());
        //2.实例化一个客户端对象
        return new VodClient(credential, vodProperties.getRegion());
    }

}
